<template>
  <div class="lc-map">
    <div class="map-legend">
      <p class="legend-area">
        <span>当前区域：</span>
        <span class="tip-title">
          <i class="loc" @click="drawMap()">中国</i>
          <i v-show="currentProvince"> / {{currentProvince}}</i>
        </span>
      </p>
      <p class="legend-tip">
        <span></span>
        <span class="tip-title">
          <i class="name">感染主机数：</i>
          <i class="num">{{stiffWoodNum}}</i>
        </span>
      </p>
    </div>
    <!-- map-inner -->
    <div class="map-inner" id="map-inner"></div>
    <!-- map 图例 -->
    <div class="map-tip"></div>
    <!-- 十段线 -->
    <div class="map-line" v-show="currentMap == 'china'"></div>
  </div>
</template>

<script>
import './style.less'
import * as d3 from 'd3'
const strokeDefault = '#4270a7', strokeLight = '#92afd3', strokeWidthDefault = '1', strokeWidthLigth = '2', textDefault = '#fff', textLight = '#ffff00';
export default {
  props: ['dataValue'],
  data() {
    return {
      currentMap: 'china',
      currentProvince: '',
      stiffWoodNum: 0
    }
  },
  components: {},
  mounted() {
    console.log(this.dataValue, 'map-self.dataValue')
    this.drawMap()
  },
  methods: {
    getNum() {
      this.stiffWoodNum = 0
      this.dataValue.map(i => {
        let num = i.doc_count
        this.stiffWoodNum += num
      })
    },

    // 绘制全国地图
    drawMap() {
      document.getElementById('map-inner').innerHTML = '' // 绘制前清空dom
      this.currentMap = 'china'
      this.currentProvince = ''
      this.getNum()
      let mapCont = document.getElementById('map-inner'),
          width = mapCont.clientWidth,
          height = mapCont.clientHeight;
      let self = this;
      d3.json('/static/map/china.json', (error, root) => {
        if (error) {
          return console.log(error)
        }
        self.projection = d3.geoMercator()
            .scale(1) // 比例尺：控制缩放
            .translate([0, 0]); // translate:偏移量

        let path = d3.geoPath()
            .projection(self.projection).pointRadius(1);
        let bounds = path.bounds(root);
        let scale = 0.80 / Math.max((bounds[1][0] - bounds[0][0]) / width, (bounds[0][1] - bounds[0][1]) / height); // 按照88%缩放
        let translate = [(width - scale * (bounds[1][0] + bounds[0][0])) / 2,
                        (height - scale * (bounds[1][1] + bounds[0][1])) / 2];
        self.projection.scale(scale).translate(translate);

        // 获取svg，绘制地图
        let svg = d3.select('#map-inner').append('svg');
        svg.attr('width', width).attr('height', height);

        /**
         * 创建发光式投影
         */
        let filter = svg.append('defs').append('filter').attr('id', 'gShadow').attr('width', '200%').attr('height', '200%');
            filter.append('feColorMatrix').attr('type', 'matrix').attr('values', () => {
              return `0 0 0 0 0
                      0 0 0 0.8 0
                      0 0 0 0.8 0
                      0 0 0 1 0`
            });
            filter.append('feGaussianBlur').attr('stdDeviation', '2').attr('result', 'colorBlur');
            filter.append('feOffset').attr('in', 'colorBlur').attr('dx', '0').attr('dy', '0').attr('result', 'colorOffsetBlur');
            filter.append('feGaussianBlur').attr('in', 'SourceAlpha').attr('stdDeviation', '10').attr('result', 'blur');
            filter.append('feOffset').attr('in', 'blur').attr('dx', '10').attr('dy', '10').attr('result', 'offsetBlur');
        let feMerge = filter.append('feMerge');
            feMerge.append('feMergeNode').attr('in', 'offsetBlur');
            feMerge.append('feMergeNode').attr('in', 'colorOffsetBlur');
            feMerge.append('feMergeNode').attr('in', 'SourceGraphic');

        /**
         * 创建径向渐变
         */
        let defaultGradient = svg.append('defs').append('radialGradient').attr('id', 'three_default_stops')
            defaultGradient.append('stop').attr('offset', '0%').attr('stop-color', '#0c142c')
            defaultGradient.append('stop').attr('offset', '50%').attr('stop-color', '#0c142c')
            defaultGradient.append('stop').attr('offset', '100%').attr('stop-color', '#0c142c')
        let lowGradient = svg.append('defs').append('radialGradient').attr('id', 'three_low_stops')
            lowGradient.append('stop').attr('offset', '0%').attr('stop-color', '#225f7d')
            lowGradient.append('stop').attr('offset', '50%').attr('stop-color', '#225f7d')
            lowGradient.append('stop').attr('offset', '100%').attr('stop-color', '#225f7d')
        let midGradient = svg.append('defs').append('radialGradient').attr('id', 'three_mid_stops')
            midGradient.append('stop').attr('offset', '0%').attr('stop-color', '#26b2d0')
            midGradient.append('stop').attr('offset', '50%').attr('stop-color', '#26b2d0')
            midGradient.append('stop').attr('offset', '100%').attr('stop-color', '#26b2d0')
        let highGradient = svg.append('defs').append('radialGradient').attr('id', 'three_high_stops')
            highGradient.append('stop').attr('offset', '0%').attr('stop-color', '#28ddfb')
            highGradient.append('stop').attr('offset', '50%').attr('stop-color', '#28ddfb')
            highGradient.append('stop').attr('offset', '100%').attr('stop-color', '#28ddfb')

        let hoverGradient = svg.append('defs').append('radialGradient').attr('id', 'three_hover_stops')
            hoverGradient.append('stop').attr('offset', '0%').attr('stop-color', '#225f7d')
            hoverGradient.append('stop').attr('offset', '50%').attr('stop-color', '#26b2d0')
            hoverGradient.append('stop').attr('offset', '100%').attr('stop-color', '#28ddfb')

        let groups = svg.append('g').attr('id', 'gGroup').attr('filter', 'url(#gShadow)').selectAll('g').data(root.features).enter().append('g'); // 对全市设置投影
        let paths = groups.append('path')
                          .attr('class', 'area')
                          .attr('stroke', function(d) {
                            let stroke = strokeDefault;
                            return stroke;
                          })
                          .attr('stroke-width', function(d) {
                            let strokeWidth = strokeWidthDefault
                            return strokeWidth;
                          })
                          .attr('d', path)
                          .attr('filter', function(d) {
                            return 'none';
                          })
                          .style('fill', function(d) {
                            let bgcolor = 'url(#three_default_stops)'
                            self.dataValue.map(i => {
                              if (d.id == i.adcode) {
                                bgcolor = i.doc_count == 0 ? 'url(#three_default_stops)'
                                          : (i.doc_count > 0 && i.doc_count < 5 * 1000 ? 'url(#three_low_stops)'
                                          : (i.doc_count > 5 * 1000 && i.doc_count < 10 * 1000 ? 'url(#three_mid_stops)'
                                          : (i.doc_count > 10 * 1000 && i.doc_count < 20 * 1000 ? 'url(#three_high_stops)' : 'url(#three_high_stops)')));
                              }
                            })
                            return bgcolor;
                          })
        console.log(paths, 'paths')

        /**
         * 添加监听事件:mouseover、mousemove、mouseout
         */
        groups.on('mouseover', function(d, i) {
          d3.select(this).select('path').style('fill', 'url(#three_hover_stops)');
          d3.select(this).select('path').style('stroke', strokeLight);
          d3.select(this).select('path').style('stroke-width', strokeWidthLigth);
          d3.select(this).select('text').style('fill', textLight);
        }).on('mouseout', function(d, i) {
            d3.select(this).select('path').style('fill', function(d) {
              let bgcolor = 'url(#three_default_stops)'
              self.dataValue.map(i => {
                if (d.id == i.adcode) {
                  bgcolor = i.doc_count == 0 ? 'url(#three_default_stops)'
                            : (i.doc_count > 0 && i.doc_count < 5 * 1000 ? 'url(#three_low_stops)'
                            : (i.doc_count > 5 * 1000 && i.doc_count < 10 * 1000 ? 'url(#three_mid_stops)'
                            : (i.doc_count > 10 * 1000 && i.doc_count < 20 * 1000 ? 'url(#three_mid_stops)' : 'url(#three_mid_stops)')));
                }
              })
              return bgcolor;
            });
            d3.select(this).select('path').style('stroke', strokeDefault);
            d3.select(this).select('path').style('stroke-width', strokeWidthDefault);
            d3.select(this).select('text').style('fill', textDefault);
          })

        // 图标
        groups.append('g').attr('class', 'stiffBg')
                          .attr('transform', function(d) {

                            // let xy = self.projection(d.properties.cp); // 经纬度坐标映射
                            // return 'translate(' + xy[0] + ',' + xy[1] + ')'; // return `translate(${xy[0]} ${xy[1]})`

                            let centroid = path.centroid(d)
                            if (d.id === '130000') { `translate(${centroid[0] - 15} ${centroid[1] + 55})`; } // 河北
                            return `translate(${centroid[0] - 15} ${centroid[1] + 5})`;
                          })
                          .append('image').attr('xlink:href', (d) => {
                            let url = ''
                            self.dataValue.map(i => {
                              if (i.adcode == d.id && i.doc_count != 0) {
                                url = '/static/map/stiffwood.svg'
                                return
                              }
                            })
                            return url
                          }).attr('width', '10').attr('height', '10');

        // text
        let nameText = groups.append('text').attr('class', 'name-tip');
        nameText.attr('x', (d) => {
              let centroid = path.centroid(d); // 中心位置坐标

              // if (d.id === '620000') { return centroid[0] - 60; } // 甘肃
              // if (d.id === '610000') { return centroid[0] + 2; }  // 陕西
              if (d.id === '450000') { return centroid[0] + 0; } // 广西
              if (d.id === '370000') { return centroid[0] + 0; } // 山东
              if (d.id === '330000') { return centroid[0] + 0; }  // 浙江
              if (d.id === '130000') { return centroid[0] - 15; } // 河北
              return centroid[0]
            })
            .attr('y', (d) => {
              let centroid = path.centroid(d);

              // if (d.id === '620000') { return centroid[1] - 35; }
              // if (d.id === '610000') { return centroid[1] + 15; }

              // if (d.id === '150000') { return centroid[1] + 15; } // 内蒙
              if (d.id === '130000') { return centroid[1] + 25; }

              // if (d.id === '110000') { return centroid[1] - 7; }  // 北京
              // if (d.id === '120000') { return centroid[1] + 12; }  // 天津

              return centroid[1]
            })
            .attr('text-anchor', 'middle')
            .attr('font-size', '14')
            .style('fill', function(d) {
              let color = textDefault;
              return color;
            })
            .text((d) => {
              return d.properties.name
            });

        let numText = groups.append('text').attr('class', 'num-tip');
        numText.attr('x', (d) => {
              let centroid = path.centroid(d); // 中心位置坐标
              return centroid[0]
            })
            .attr('y', (d) => {
              let centroid = path.centroid(d);
              return centroid[1]
            })
            .attr('dx', (d) => {
              return 0;
            })
            .attr('dy', (d) => {
              return 16;
            })
            .attr('text-anchor', 'left') // 控制字体显示方式：left middle right
            .attr('font-size', '14')
            .style('fill', function(d) {
              let color = textLight;
              return color;
            })
            .text((d) => {
              let unit = ''
              self.dataValue.map(i => {
                if (i.adcode == d.id) {
                 unit = i.doc_count == 0 ? '' : i.doc_count
                }
              })
              return unit
            });

        /**
         * 添加点击事件
         */
        groups.on('click', function(d, i) {
          d3.select('#map-inner svg').selectAll('g').remove();
          console.log(d, 'dd--')
          self.dataValue.map(i => {
            if (i.adcode == d.id) {
              self.stiffWoodNum = i.doc_count
            }
          })
          self.drawDistMap(d.id, d.properties.name);
        });
      })
    },

    // 绘制省/直辖市地图
    drawDistMap(distId, distProvince) {
      console.log(distId, 'distMap-distId')

      // 清除dom，防止堆积
      d3.select('#map-inner svg').selectAll('g').remove();
      d3.select('#map-inner svg').selectAll('defs').remove();
      this.currentMap = 'other'
      this.currentProvince = distProvince
      let mapCont = document.getElementById('map-inner'),
            width = mapCont.clientWidth,
            height = mapCont.clientHeight - 30;
      let distRegion = distId;

      let self = this;

        /**
         * 加载区域地图geojson并进行绘制
         */
        d3.json('/static/map/province/' + distRegion + '.json', (distError, distRoot) => {
          if (distError) {
            return console.error(distError);
          }
          let distProjection = d3.geoMercator()
                                .scale(1)
                                .translate([0, 0]);
          let distPath = d3.geoPath()
                          .projection(distProjection).pointRadius(1);
          let distBounds = distPath.bounds(distRoot);
          let distScale = 0.90 / Math.max((distBounds[1][0] - distBounds[0][0]) / width, (distBounds[1][1] - distBounds[0][1]) / height);
          let distTranslate = [(width - distScale * (distBounds[1][0] + distBounds[0][0])) / 2,
                          (height - distScale * (distBounds[1][1] + distBounds[0][1])) / 2];
          distProjection.scale(distScale).translate(distTranslate);

          // 绘制区域地图
          let distSvg = d3.select('#map-inner svg');
          distSvg.attr('width', width).attr('height', height).attr('transform', 'translate(0, 0)');

          /**
          * 创建发光式投影
          */
          let distfilter = distSvg.append('defs').append('filter').attr('id', 'distgShadow').attr('width', '200%').attr('height', '200%');
              distfilter.append('feColorMatrix').attr('type', 'matrix').attr('values', () => {
                return `0 0 0 0 0
                        0 0 0 0.9 0
                        0 0 0 0.9 0
                        0 0 0 1 0`
              });
              distfilter.append('feGaussianBlur').attr('stdDeviation', '2').attr('result', 'colorBlur');
              distfilter.append('feOffset').attr('in', 'colorBlur').attr('dx', '0').attr('dy', '0').attr('result', 'colorOffsetBlur');
              distfilter.append('feGaussianBlur').attr('in', 'SourceAlpha').attr('stdDeviation', '10').attr('result', 'blur');
              distfilter.append('feOffset').attr('in', 'blur').attr('dx', '10').attr('dy', '10').attr('result', 'offsetBlur');
          let distfeMerge = distfilter.append('feMerge');
              distfeMerge.append('feMergeNode').attr('in', 'offsetBlur');
              distfeMerge.append('feMergeNode').attr('in', 'colorOffsetBlur');
              distfeMerge.append('feMergeNode').attr('in', 'SourceGraphic');

          let defaultGradient = distSvg.append('defs').append('radialGradient').attr('id', 'three_default_stops')
              defaultGradient.append('stop').attr('offset', '0%').attr('stop-color', '#0c142c')
              defaultGradient.append('stop').attr('offset', '50%').attr('stop-color', '#0c142c')
              defaultGradient.append('stop').attr('offset', '100%').attr('stop-color', '#0c142c')
          let lowGradient = distSvg.append('defs').append('radialGradient').attr('id', 'three_low_stops')
              lowGradient.append('stop').attr('offset', '0%').attr('stop-color', '#225f7d')
              lowGradient.append('stop').attr('offset', '50%').attr('stop-color', '#225f7d')
              lowGradient.append('stop').attr('offset', '100%').attr('stop-color', '#225f7d')
          let midGradient = distSvg.append('defs').append('radialGradient').attr('id', 'three_mid_stops')
              midGradient.append('stop').attr('offset', '0%').attr('stop-color', '#26b2d0')
              midGradient.append('stop').attr('offset', '50%').attr('stop-color', '#26b2d0')
              midGradient.append('stop').attr('offset', '100%').attr('stop-color', '#26b2d0')
          let highGradient = distSvg.append('defs').append('radialGradient').attr('id', 'three_high_stops')
              highGradient.append('stop').attr('offset', '0%').attr('stop-color', '#28ddfb')
              highGradient.append('stop').attr('offset', '50%').attr('stop-color', '#28ddfb')
              highGradient.append('stop').attr('offset', '100%').attr('stop-color', '#28ddfb')

          let hoverGradient = distSvg.append('defs').append('radialGradient').attr('id', 'three_hover_stops')
              hoverGradient.append('stop').attr('offset', '0%').attr('stop-color', '#225f7d')
              hoverGradient.append('stop').attr('offset', '50%').attr('stop-color', '#26b2d0')
              hoverGradient.append('stop').attr('offset', '100%').attr('stop-color', '#28ddfb')

          let distGroups = distSvg.append('g').attr('id', 'distgGroup').attr('filter', 'url(#distgShadow)').selectAll('g').data(distRoot.features).enter().append('g');
          let distData = []

          self.dataValue.map(i => {
            if (i.adcode == distId) { distData = i.districts; }
            return
          })
          console.log(distData, 'd0d0d0d0d--')
          let distPaths = distGroups.append('path')
                                    .attr('class', 'dist')
                                    .attr('stroke', function(d) {
                                      let stroke = strokeDefault;
                                      return stroke;
                                    })
                                    .attr('stroke', 'none')
                                    .attr('d', distPath)
                                    .style('fill', function(d) {

                                      // let bgcolor = bgfillDefault;
                                      let bgcolor = 'url(#three_default_stops)';
                                      console.log(distData, 'distData--')
                                      distData.map(i => {
                                        if (d.properties.id == i.adcode) {
                                          bgcolor = i.doc_count == 0 ? 'url(#three_default_stops)'
                                                  : (i.doc_count > 0 && i.doc_count < 5 * 1000 ? 'url(#three_low_stops)'
                                                  : (i.doc_count > 5 * 1000 && i.doc_count < 10 * 1000 ? 'url(#three_mid_stops)'
                                                  : (i.doc_count > 10 * 1000 && i.doc_count < 20 * 1000 ? 'url(#three_high_stops)' : 'url(#three_high_stops)')));
                                        }
                                      })
                                      console.log(bgcolor, 'bgcolor--dist')
                                      return bgcolor
                                    });
          console.log(distPaths);

          // 图标
        distGroups.append('g').attr('class', 'stiffBg')
                          .attr('transform', function(d) {
                            let centroid = distPath.centroid(d)
                            return `translate(${centroid[0] - 15} ${centroid[1] + 5})`;
                          })
                          .append('image').attr('xlink:href', (d) => {
                            let url = ''
                            distData.map(i => {
                              if (i.adcode == d.properties.id && i.doc_count != 0) {
                                url = '/static/map/stiffwood.svg'
                                return
                              }
                            })
                            return url
                          }).attr('width', '10').attr('height', '10');

          // text
          let distNameText = distGroups.append('text').attr('class', 'distName-tip');
          distNameText.attr('x', (d) => {
                let centroid = distPath.centroid(d); // 中心位置坐标
                return centroid[0]
              })
              .attr('y', (d) => {
                let centroid = distPath.centroid(d);
                return centroid[1]
              })
              .attr('text-anchor', 'middle')
              .attr('font-size', '14')
              .style('fill', function(d) {
                let color = textDefault;
                return color;
              })
              .text((d) => {
                return d.properties.name
              });
          let distNumText = distGroups.append('text').attr('class', 'dist-num-tip');
          console.log(distNumText, 'distNumText--')
          distNumText.attr('x', (d) => {
                let centroid = distPath.centroid(d); // 中心位置坐标
                return centroid[0]
              })
              .attr('y', (d) => {
                let centroid = distPath.centroid(d);
                return centroid[1]
              })
              .attr('dx', (d) => {
                return 0;
              })
              .attr('dy', (d) => {
                return 16;
              })
              .attr('text-anchor', 'left') // 控制字体显示方式：left middle right
              .attr('font-size', '14')
              .style('fill', function(d) {
                let color = textLight;
                return color;
              })
              .text((d) => {
                let unit = ''
                console.log(d, 'id---')
                distData.map(i => {
                  if (i.adcode == d.properties.id) {
                  unit = i.doc_count == 0 ? '' : i.doc_count
                  }
                })
                return unit
              });
          });
    }
  }
}
</script>
